from airtest.core.api import *
import threading

class BaseCoordinates:
    def __init__(self):
        pass
class CoordinatesResolution_1600_900(BaseCoordinates):
    def __init__(self):
        super().__init__()
        # 设置分辨率1600*900的坐标参数
        self.UICoordinates = {
            'CombatButton': [1122, 93],
            'SystemButton': [1251, 93],
            'SignalListButton': [1508, 368],
            'ScanButton': [800, 715],
            'GalaxyButton': [1381, 91],
            'GalaxyListButton': [1513, 370],
            'SkipButton': [1408, 677],
            'SocialButton': [1521, 72],
            'ChatButton': [1309, 106],
            'ChatTextLineInput': [1053, 837],
            'SystemInputComfirmButton': [1493, 802],
            'GreenChatTextSendButton': [1496, 816],
            'GroupButton': [1514, 557],
            'CreateGroupButton': [1187, 456],
            'SocialCloseButton': [1514, 54],
            'SignalMissionSettlementBackToStation': [977, 778],
            'SignalMissionSettlementStay':[597, 775],
            'LowerLeftBlankSpace': [472, 482],
            'EmergencyJumpButton': [1195, 96],
            'EmergencyJumpYesButton': [1385, 91],
            'EnemyAttackButton':[1122,494],
            'RedTargetButton':[1506,370],
            'RedTargetList_FirstTarget':[1188,302],
            'BlueTargetButton': [1506, 545],
            'BlueTargetList_FirstTarget': [1235, 301],
            'BlueTargetListFirstTarget_MoveButton': [1297, 510],
            'BlueTargetListFirstTarget_InterceptButton': [1119, 510],
            'JoannaTalkSkipButton': [821, 340],
            'LostConnectionRestartButton': [800, 720],
            'StartGameButton': [790, 766],
            'AdvertisementCloseButton': [1064, 105],
            'FirstSkill': [82, 364],
            'SecondSkill': [83, 451],
            'ThirdSkill': [88, 536],
            'FourthSkill': [85, 622],
            'GroupSignalList_AboveSignal': [1623, 838],
            'GroupSignalList_UnderSignal': [1600, 966]
        }
        self.UIConfig = {
            'resolution' : (1600, 900)
        }
class CoordinatesResolution_2176_1224(BaseCoordinates):
    def __init__(self):
        super().__init__()
        # 设置分辨率2176*1224的坐标参数
        self.UICoordinates = {
            'CombatButton': [1525, 122],
            'SystemButton': [1704, 123],
            'GalaxyButton': [1877, 129],
            'SignalListButton': [2052, 504],
            'AsteroidClusterButton': [2053,737], # 在System中的小行星带 不是矿物资源
            'AsteroidCluster_FirstItem':[1645,407],
            'AsteroidCluster_FirstItem_MoveButton':[1765,683],
            'Combat_AsteroidClusterButton':[2049,859],
            'Combat_AsteroidClusterButton_FirstItem':[1650,404],
            'Combat_AsteroidClusterButton_FirstItem_MoveButton':[1769,674], # Little Trick 这个地方可以把点击位置放在Move上
            'Combat_AsteroidClusterButton_FirstItem_MineButton':[1575,686], # 非常奇怪 这个位置似乎总是一个D类型的矿物


            'Combat_AsteroidClusterButton_ForthItem':[1745,797],
            'Combat_AsteroidClusterButton_ForthItem_MoveButton':[1808,760], 
            'Combat_AsteroidClusterButton_ForthItem_MineButton':[1598,763], 


            'GalaxyListButton': [2054, 504],
            'CurrentGalaxyItem':[1611,408],
            'CurrentGalaxyItemMoveButton':[1786,685],
            'FirstGalaxyItem':[1616,482], # 第一个是自己 所以这里的第一个是可以跃迁的第一个
            'FirstGalaxyItemMoveButton':[1765,768],

            'InternalButton': [292, 118],
            'CloseInternalButton': [2057, 147],
            'StorageButton': [406, 391],
            'MultiSelectButton': [1940, 1134],
            'MultiSelectCheckBoxButton': [232, 304],
            'StashButton': [1145, 1138],
            'StashCheckButton': [1312, 1069],

            'ResearchButton':[1430,954],
            'CollectResearchPoint':[1654,1072],

            'ScanButton': [1083, 984],
            'SkipButton': [1931, 919],
            'SocialButton': [2056, 107],
            'ChatButton': [1786, 138],
            'ChatTextLineInput': [1492, 1135],
            'SystemInputComfirmButton': [2088, 1173],
            'GreenChatTextSendButton': [2033, 1104],
            'GroupButton': [2056, 758],
            'CreateGroupButton': [1615, 620],
            'SocialCloseButton': [2057, 74],
            'SignalMissionSettlementBackToStation': [1329, 1061],
            'SignalMissionSettlementStay':[811, 1057],
            'LowerLeftBlankSpace': [537, 790],
            'EmergencyJumpButton': [1526, 133],
            'EmergencyJumpYesButton': [1873, 121],
            'EnemyAttackButton':[1524,670],
            'RedTargetButton':[2050,504],
            'RedTargetList_FirstTarget':[1583,407],
            'BlueTargetButton': [2041, 738],
            'BlueTargetList_FirstTarget': [1621, 410],
            'BlueTargetListFirstTarget_MoveButton': [1762, 691],
            'BlueTargetListFirstTarget_InterceptButton': [1524, 692],
            'JoannaTalkSkipButton': [1139, 459],
            'JoannaSignalJumpSkipButton': [1618,1116],
            'LostConnectionRestartButton': [1080, 974],
            'StartGameButton': [1080, 1038],
            'AdvertisementCloseButton': [1978, 128],
            'FirstSkill': [118, 492],
            'SecondSkill': [114, 609],
            'ThirdSkill': [113, 729],
            'FourthSkill': [111, 845],
            'GroupSignalList_AboveSignal': [1511, 823],
            'GroupSignalList_UnderSignal': [1499, 959]
        }
        self.UIConfig = {
            'resolution' : (2176, 1224)
        }

class galaxyImagePathConfig:
    def __init__(self):
        self.images = {
            "DEVADAASI": "./resources/galaxyNameList/DEVADAASI.png",
            "NIIREA PAAS": "./resources/galaxyNameList/NIIREA PAAS.png",
            "KALUARI": "./resources/galaxyNameList/KALUARI.png",
            "KEID": "./resources/galaxyNameList/KEID.png",
            "VISAAN KI": "./resources/galaxyNameList/VISAAN KI.png",
            "JONALLI": "./resources/galaxyNameList/JONALLI.png",
            "LIUSATA": "./resources/galaxyNameList/LIUSATA.png",
            "KISHO RE": "./resources/galaxyNameList/KISHO RE.png",
            "SOBEL REM": "./resources/galaxyNameList/SOBEL REM.png",
            "BESCAVA": "./resources/galaxyNameList/BESCAVA.png",
            "LARCAVA": "./resources/galaxyNameList/LARCAVA.png",
            "COIXL": "./resources/galaxyNameList/COIXL.png",
            "IXTLAN": "./resources/galaxyNameList/IXTLAN.png",
            "TECOACUI": "./resources/galaxyNameList/TECOACUI.png",
            "TELAPENTE": "./resources/galaxyNameList/TELAPENTE.png",
            "CUERNAVA": "./resources/galaxyNameList/CUERNAVA.png",
            "ZEMPOALA": "./resources/galaxyNameList/ZEMPOALA.png",
            "TEPECOAL": "./resources/galaxyNameList/TEPECOAL.png",
            "ACATLAHU": "./resources/galaxyNameList/ACATLAHU.png",
            "TLACOZAU": "./resources/galaxyNameList/TLACOZAU.png",
            "XALAPAN": "./resources/galaxyNameList/XALAPAN.png",
            "CHUUA": "./resources/galaxyNameList/CHUUA.png",
            "TANOCHETLAN": "./resources/galaxyNameList/TANOCHETLAN.png"
        }
    def get_values(self, keys):
        values = []
        for key in keys:
            value = self.images.get(key)  # 使用get()方法来获取值，如果键不存在，则返回None
            values.append(value)
        # [images.get(key) for key in keyList]
        return values
    


class GameControllor: # 游戏UI控制模块
    def __init__(self,coordinates_resolution):
        self.galaxySignalMissionReady = True
        self.lostConnectionCheck = False        # no need to init at first 
        self.connectionCheckInterval = 60 * 5   # 按照5分钟的周期检查掉线情况
        self.checkLostConnectThread = None      # 初始化掉线检查线程变量
        self.disconnectedCount = 0              # 掉线重连的次数
        self.flags = []                         # 需要进行通知断线重连的标志位
        self.coordinates_resolution = coordinates_resolution

    def launch_app(self):   # 启动游戏
        start_app("com.stratospheregames.nimbusgbx")
    
    def close_app(self):    # 关闭游戏  
        stop_app("com.stratospheregames.nimbusgbx")


    def resetToMainScreen(self):
        touch(self.coordinates_resolution.UICoordinates['CombatButton'])   
        sleep(3.0)
        touch(self.coordinates_resolution.UICoordinates['CombatButton'])  
        playerHeadPicCheck = exists(Template(r"./resources/customFeature/playerPic.png", record_pos=(-0.446, -0.231), resolution=self.coordinates_resolution.UIConfig['resolution'])) 
        if playerHeadPicCheck:  # 检查当前正在MainScreen
            return True 
        else:   
            log("某些奇怪的错误发生了,为什么没有回到主界面?")
            return False
    def moveToCombatScreent(self):
        touch(self.coordinates_resolution.UICoordinates['CombatButton']) 
        sleep(1.0)
        touch(self.coordinates_resolution.UICoordinates['CombatButton']) 
        sleep(1.0)
        touch(self.coordinates_resolution.UICoordinates['CombatButton']) 
        sleep(1.0)    # 进入系统需要一定的缓冲刷新
        
    def moveToSystemScreen(self):   # 进入System界面 前置条件:在商店不行
        touch(self.coordinates_resolution.UICoordinates['SystemButton']) 
        sleep(1.0)
        touch(self.coordinates_resolution.UICoordinates['SystemButton']) 
        sleep(1.0)
        touch(self.coordinates_resolution.UICoordinates['SystemButton']) 
        sleep(1.0)    # 进入系统需要一定的缓冲刷新
    
    def openSignalList(self):
        touch(self.coordinates_resolution.UICoordinates['SignalListButton'])   
        return True

    def moveToGalaxy(self):
        touch(self.coordinates_resolution.UICoordinates['GalaxyButton'])
        sleep(3.0)
        
    def toScan(self,timeInterval = 8.0):
        touch(self.coordinates_resolution.UICoordinates['ScanButton'])   # Scan! 应该配合进入System或者Galaxy使用!
        touch(self.coordinates_resolution.UICoordinates['ScanButton'])   # 防止没有点上 再来一次
        sleep(timeInterval)     # 默认间隔8秒才能执行下一次
    
    def multipleScan(self,scanTime):
        for index in range(scanTime):   # 进行多次扫描
            self.toScan()

    def moveToGalaxyAndOpenList(self):  # make sure that you are in the main screen to do this
        touch(self.coordinates_resolution.UICoordinates['GalaxyButton'])   # open galaxy screen
        sleep(3.0)
        touch(self.coordinates_resolution.UICoordinates['GalaxyListButton'])  # Click and open galaxy list
        sleep(3.0)
    
    def jumpIntoAsteroidCluster_FirstItem(self):
        touch(self.coordinates_resolution.UICoordinates['AsteroidClusterButton'])   # open galaxy screen
        sleep(1.5)
        touch(self.coordinates_resolution.UICoordinates['AsteroidCluster_FirstItem'])  
        sleep(1.5)
        touch(self.coordinates_resolution.UICoordinates['AsteroidCluster_FirstItem_MoveButton'])  

    def backToCurrentGalaxy(self):
        touch(self.coordinates_resolution.UICoordinates['CurrentGalaxyItem'])
        sleep(1.0)
        touch(self.coordinates_resolution.UICoordinates['CurrentGalaxyItemMoveButton'])
        touch(self.coordinates_resolution.UICoordinates['CurrentGalaxyItemMoveButton'])
        touch(self.coordinates_resolution.UICoordinates['CurrentGalaxyItemMoveButton'])
    def clickGalaxListFirstItemMoveButton(self):
        touch(self.coordinates_resolution.UICoordinates['FirstGalaxyItem'])
        sleep(1.0)
        touch(self.coordinates_resolution.UICoordinates['FirstGalaxyItemMoveButton'])
        touch(self.coordinates_resolution.UICoordinates['FirstGalaxyItemMoveButton'])
        touch(self.coordinates_resolution.UICoordinates['FirstGalaxyItemMoveButton'])

    def clickSkipButton(self):
        for index in range(5):
            touch(self.coordinates_resolution.UICoordinates['SkipButton'])
            sleep(1.0)  # 保证能完全的跳过加载过程 这一点加载时间可能会影响整个循环
            touch(self.coordinates_resolution.UICoordinates['SkipButton']) 

    def clickGameBlankSpace(self): # 常用来纠正画面
        touch(self.coordinates_resolution.UICoordinates['LowerLeftBlankSpace'])

    def openSocial(self):   # 开始条件 应该是主界面 不然点不了右上角的图标
        touch(self.coordinates_resolution.UICoordinates['SocialButton'])   # Open channel list
        sleep(1.0)
    
    def switchToChat(self): # 打开通信之后确定不是进入邮箱而是通信列表 
        touch(self.coordinates_resolution.UICoordinates['ChatButton'])  # ChatButton
        log("确认切换到ChatList")
        sleep(1.0)
    
    def openChatTextInputLine(self):    # 打开输入框 但是还没有输入内容
        touch(self.coordinates_resolution.UICoordinates['ChatTextLineInput'])  # ChatTextLineInput
        sleep(1.0)
    
    def inputTextAndSend(self):
        # input输入框输入内容 请提前已经打开输入框了 也就是已经打开输入法界面了
        # ready to create channel 准备开始在输入框输入内容
        for i in range(10): # 清除输入框内容
            keyevent("KEYCODE_DEL")
        text("/join 21", enter=True)
        sleep(1.0)  # SystemInputComfirmButton 系统输入框的确认按钮
        touch(self.coordinates_resolution.UICoordinates['SystemInputComfirmButton'])  
        sleep(1.0)  # GreenChatTextSendButton 点击游戏内的输入信息的绿色的回车
        touch(self.coordinates_resolution.UICoordinates['GreenChatTextSendButton'])  
        sleep(1.0)
    
    def openGroupList(self):    # open group list
        touch(self.coordinates_resolution.UICoordinates['GroupButton'])  # GroupButton
        log("打开GroupList")
        sleep(1.0)
    
    def createGroup(self):  # create group 创建队伍
        log("准备点击创建队伍按钮")
        touch(self.coordinates_resolution.UICoordinates['CreateGroupButton'])  # CreateGroupButton
        sleep(1.0)
    
    def closeSocialList(self):
        touch(self.coordinates_resolution.UICoordinates['SocialCloseButton']) # SocialCloseButton
        log("关闭Social功能!")
    
    def clickCreditsStayButton(self):  # 留在原地
        touch(self.coordinates_resolution.UICoordinates['SignalMissionSettlementStay'])   
        sleep(1.0) # 确保真的点到了避免卡顿 
        touch(self.coordinates_resolution.UICoordinates['SignalMissionSettlementStay'])   
        
    def clickCreditsGoToStationButton(self):   # 返回空间站
        touch(self.coordinates_resolution.UICoordinates['SignalMissionSettlementBackToStation'])
        sleep(1.0)   # 确保真的点到了避免卡顿 SignalMissionSettlementBackToStation
        touch(self.coordinates_resolution.UICoordinates['SignalMissionSettlementBackToStation'])   
        
    def joinChannelAndGroup(self):  # 用来加入频道并进入队伍 从主界面(可能)来最后回到主界面
        log("准备开始创建Group")
        self.openSocial()
        self.switchToChat()
        self.openChatTextInputLine()
        self.inputTextAndSend()
        log("成功加入频道21!")
        self.openGroupList()
        self.createGroup()
        log("成功加入Group!")
        self.closeSocialList()
        self.resetToMainScreen()
        
    def closeCommunicationLsitUI(self):
        touch(self.coordinates_resolution.UICoordinates['SocialCloseButton'])   
        # 关闭通信界面 
        touch(self.coordinates_resolution.UICoordinates['LowerLeftBlankSpace'])   
        sleep(2.5) # 关闭GroupUI  LowerLeftBlankSpace 这个时间不能太小 因为加载会慢
        touch(self.coordinates_resolution.UICoordinates['LowerLeftBlankSpace'])

    def findSignalStartButtonAndBeginMission(self) -> bool: # 选中一个Signal之后检索Start按钮进入
        startButtonExistCheck = exists(Template(r"./resources/commonCommand/SignalStartButton.png", record_pos=(0.253, 0.072), resolution=self.coordinates_resolution.UIConfig['resolution']))
        if startButtonExistCheck == False:
            return False
        log("导航员:准备进入战场!")
        touch(startButtonExistCheck)
        return True
        
    def emergencyJump(self): # 在战场上紧急跃迁
        touch(self.coordinates_resolution.UICoordinates['EmergencyJumpButton']) # 点击紧急跳跃
        sleep(2.0)
        touch(self.coordinates_resolution.UICoordinates['EmergencyJumpYesButton'])   # 触发确认 

    def recordSignalMission(self): # 假设已经完成了队伍创建 并且已经刷新出来了两个信号 现在等待记录两个信号
        # TODO 现在只能直接固定两个类型的任务 第一个是Progenitor 同类型的还有Tanoch 第二个是Relic
        log("准备开始信号记录到Group")
        self.resetToMainScreen()  # 从主界面开始这个任务
        self.moveToSystemScreen()
        self.openSignalList()
        log("UI控制程序:正在检索Progenitor信号")
        ProgenitorSignal = exists(Template(r"./resources/signalType/ProgenitorSignal.png", record_pos=(0.284, 0.014), resolution=self.coordinates_resolution.UIConfig['resolution']))
        if ProgenitorSignal:
            log("准备记录Progenitor信号")
            touch(ProgenitorSignal)
            sleep(3.0)
            self.findSignalStartButtonAndBeginMission()
            self.clickSkipButton()
            sleep(45.0)             # 保证战场加载完毕的最小时间
            self.emergencyJump()
            log("信号记录完毕,准备跃迁!")
            self.clickSkipButton()  # 需要这一步骤 防止舰队人没有快速归队
            sleep(40.0)             # 保证真的加载完毕的最小时间
            log("Progenitor信号准备完毕!")
        else:
            log("Progenitor信号检索失败,没有发现该信号")
            return False
        log("准备开始信号记录到Group")
        self.resetToMainScreen()
        self.moveToSystemScreen()
        self.openSignalList()
        # locate second mission
        RelicSignal = exists(Template(r"./resources/signalType/RelicSignal.png", record_pos=(0.284, 0.014), resolution=self.coordinates_resolution.UIConfig['resolution']))
        if RelicSignal:
            log("准备记录Relic信号")
            touch(RelicSignal)
            sleep(3.0)
            self.findSignalStartButtonAndBeginMission()
            self.clickSkipButton()
            sleep(45.0)             # 保证战场加载完毕的最小时间
            self.emergencyJump()
            self.clickSkipButton()  # 需要这一步骤 防止舰队人没有快速归队
            sleep(40.0)             # 保证真的加载完毕的最小时间
            log("Relic信号准备完毕!")
        else:
            log("Relic信号检索失败,没有发现该信号")
            return False
        return True

    def clickJoannaSignalJumpSkip(self):
        for index in range(5):
            touch(self.coordinates_resolution.UICoordinates['JoannaSignalJumpSkipButton'])
            sleep(1.0)
    def openBlueTargetList(self): # 打开物资列表
        touch(self.coordinates_resolution.UICoordinates['BlueTargetButton'])  
        sleep(1.0)

    def chooseFirstBlueTargetAndMove(self): # 需要打开List列表
        touch(self.coordinates_resolution.UICoordinates['BlueTargetList_FirstTarget'])   
        sleep(1.5)  # 舰队协同保护矿机 前进Move
        touch(self.coordinates_resolution.UICoordinates['BlueTargetListFirstTarget_MoveButton'])   # 舰队前去目标位置 绿色的实心箭头
        touch(self.coordinates_resolution.UICoordinates['BlueTargetListFirstTarget_MoveButton'])
        sleep(1.5)  # UI加载时间

    def chooseFirstBlueTargetAndIntercept(self): # 需要打开List列表
        touch(self.coordinates_resolution.UICoordinates['BlueTargetList_FirstTarget']) 
        sleep(1.5)  # 开始回收工作 保证控制窗回收
        touch(self.coordinates_resolution.UICoordinates['BlueTargetListFirstTarget_InterceptButton'])   
        touch(self.coordinates_resolution.UICoordinates['BlueTargetListFirstTarget_InterceptButton'])   

    def AbandonedFreightContainerLocate(self): # 物资检查
        AbandonedFreightContainerLocation = exists(Template(r"./resources/signalResources/AbandonedFreightContainer.png", record_pos=(
            0.281, -0.096), resolution=self.coordinates_resolution.UIConfig['resolution']))
        if AbandonedFreightContainerLocation: # 打开物资控制面板
            touch(AbandonedFreightContainerLocation)
            sleep(1.0)
            return True
        else:
            return False

    def ProgenitorArtifactLocate(self): # AbandonedFreightContainer 物资检查
        resourceCheck = exists(Template(r"./resources/signalResources/ProgenitorArtifact.png", record_pos=(0.249, -0.095), resolution=self.coordinates_resolution.UIConfig['resolution']))
        if resourceCheck: # 打开物资控制面板
            touch(resourceCheck)
            sleep(1.0)
            return True
        else:
            return False

    def TargetPositionLocate(self): # TargetPosition 物资检查
        touch(self.coordinates_resolution.UICoordinates['BlueTargetList_FirstTarget'])
        sleep(1.0)

    def moveToTargetResources():    # 开启目标资源行动之后开始准备舰队移动
        sleep(1.0) # 绿色的Move操作
        touch(self.coordinates_resolution.UICoordinates['BlueTargetListFirstTarget_MoveButton'])   
        
    def collectorInterpack():   # collectorInterpack 矿机准备进行回收工作
        interpackCheck = exists(Template(
                r"./resources/commonCommand/Interpact.png", record_pos=(0.229, 0.036), resolution=self.coordinates_resolution.UIConfig['resolution']))
        if interpackCheck:
                touch(interpackCheck)
                sleep(5.0)  # 给出足够的行动时间
                return True
        else:
            return False
    
    def rewardSettlement(self):
        communicationsOfficerCheck = exists(Template(
            r"./resources/signalResources/communicationsOfficer.png", record_pos=(-0.336, -0.149), resolution=self.coordinates_resolution.UIConfig['resolution']))
        if communicationsOfficerCheck: # 和通信官对话,触发奖励结算
            for index in range(3):
                touch(self.coordinates_resolution.UICoordinates['JoannaTalkSkipButton'])       
                sleep(2.0)
            touch(self.coordinates_resolution.UICoordinates['JoannaTalkSkipButton'])
            sleep(10.0)  # 等待奖励结算         
            return True
        else:
            return False

    def registerConnectionCheckFlag(self,actionFlagObject):
        self.flags.append(actionFlagObject) # the actionFlag should be reference of a object

    def stopAllFlag(self):
        for flag in self.flags:
            log("游戏检查程序:通知"+str(flag)+"停止行动")
            flag.connectionReadyToWorkFlag = False

    def startAllFlag(self):
        for flag in self.flags:
            log("游戏检查程序:通知"+str(flag)+"可以继续行动")
            flag.connectionReadyToWorkFlag = True

    def checkLostConnect(self):
        first_time = True # 检查是否是第一次执行,在常规情况下第一次是不用进行掉线检查的
        while True:
            log("UI控制程序:掉线发现的次数:"+str(self.disconnectedCount)+"次")
            """ 
            if first_time:  # 第一次执行的时候并不进行检查 放行舰队行动
                log("游戏检查程序:第一次连接检查默认连接正常")
                self.startAllFlag()
                first_time = False  # 结束第一次的状态
                sleep(self.connectionCheckInterval) 
            log("游戏检查程序:准备检查连接情况") 
            """
            warningFlagCheck = exists(Template(r"./resources/lostConnectionFeature/WarningFlag.png", record_pos=(0.002, -0.092), resolution=self.coordinates_resolution.UIConfig['resolution']))
            startGameButtonCheck = exists(Template(r"./resources/startGameFeature/startGameButton.png", record_pos=(-0.002, 0.197), resolution=self.coordinates_resolution.UIConfig['resolution']))
            if warningFlagCheck == False or startGameButtonCheck == False:
                log("游戏检查程序:连接状态良好")
                self.startAllFlag()  # 舰队可以继续执行任务
                sleep(self.connectionCheckInterval) # 继续周期性检查掉线情况 
            else:    # 准备重新连接
                log("游戏检查程序:检查到掉线情况发生,准备重新连接")
                self.disconnectedCount += 1
                self.stopAllFlag()
                log("UI控制程序:点击重新开始按钮")
                touch(self.coordinates_resolution.UICoordinates['LostConnectionRestartButton'])    
                sleep(60.0 * 3)         # 保证充足的加载时间缓冲
                startGameCheck = exists(Template(r"./resources/startGameFeature/startGameButton.png", record_pos=(-0.001, 0.197), resolution=self.coordinates_resolution.UIConfig['resolution']))
                if startGameCheck==False:
                    sleep(30.0 * 3) # 如果没有加载成功那么延迟继续加载
                else:
                    startGameFinishedCheck = self.startGameandClearAdvertisement()
                    if startGameFinishedCheck == True:  # 准备开始连接到游戏
                        self.startAllFlag()             # 舰队可以继续执行任务
                    sleep(self.connectionCheckInterval) # 继续周期性检查掉线情况
    
    def startCheckLostConnect(self):
        log("游戏控制程序:开始监控游戏连接情况")
        # 如果线程已经在运行，那么就不需要再启动了
        if self.checkLostConnectThread is not None and self.checkLostConnectThread.is_alive():
            return
        # 创建一个新的线程
        self.checkLostConnectThread = threading.Thread(target=self.checkLostConnect, args=())
        # 将线程设置为守护线程，这样当主线程结束时，子线程也会随之结束
        self.checkLostConnectThread.daemon = True
        self.checkLostConnectThread.start() # 启动线程
    
    def stopCheckLostConnect(self): # 停止执行checkLostConnect方法
        # 如果线程已经在运行，那么就停止它
        if self.checkLostConnectThread is not None and self.checkLostConnectThread.is_alive():
            self.checkLostConnectThread.stop()

    def startGameandClearAdvertisement(self):   # 准备开始检测是否存在目标
        welcomeFlagCheck = exists(Template(r"./resources/startGameFeature/welcomeFlag.png", record_pos=(-0.081, -0.221), resolution=self.coordinates_resolution.UIConfig['resolution']))
        startGameButtonCheck = exists(Template(r"./resources/startGameFeature/startGameButton.png", record_pos=(-0.002, 0.197), resolution=self.coordinates_resolution.UIConfig['resolution']))
        if welcomeFlagCheck or startGameButtonCheck:    # 只要检查到其中一个可以启动游戏的特征就可以继续
            touch(self.coordinates_resolution.UICoordinates['StartGameButton'])    # 点击开始游戏按钮
            sleep(35.0)         # 游戏加载时间
        sleep(30.0)     # 等待游戏加载时间长一点 这是一个可能错位的地方
        log("UI控制程序:准备关闭广告")
        touch(self.coordinates_resolution.UICoordinates['AdvertisementCloseButton'])
        sleep(10.0)     # 短暂的加载时间
        # 检查是否进入游戏MainScreen
        # checkEnterGameState = exists(Template(r"./resources/customFeature/playerPic.png", record_pos=(-0.446, -0.231), resolution=self.coordinates_resolution.UIConfig['resolution']))
        return True  # 检查当前是否进入游戏界面

class FleetCommander:   # 管理所有舰队的Galaxy行动 Galaxy功能模块
    def __init__(self,GameControllor_instance,coordinates_resolution,imagePathList = []):
        self.stations = []              # Template list
        self.current_station_index = 0  # 记录当前在第几站
        self.direction = 1              # 从起始站出发为正方向设置为1 终点为反方向设置为-1
        self.connectionReadyToWorkFlag = False       # 当前是否可以执行任务
        self.gameControllor = GameControllor_instance
        self.coordinates_resolution = coordinates_resolution
        self.initGalaxyTemplateResources(imagePathList)

    def fleetCommanderInitTest():
        log("FleetCommander init success")

    def callMethodByName(methodName, targetClass,*args):
        # 这里定义了一个工具类函数它的意义是为了通过一个字符串来调用一个方法
        # 该方法返回一个函数的指向 仍然需要手动调用
        targetMethod = getattr(targetClass, methodName)
        targetMethod(*args) # 执行我们需要的目标方法
    
    def initGalaxyTemplateResources(self,imagePathList):    # 初始化一个路线
        # log(str(imagePathList))
        for elem in imagePathList:
            # 此处的record_pos已经优化为GalaxyList的UI框内,提高了很多准确程度
            self.stations.append(Template(elem,record_pos=(0.284, 0.014),resolution=self.coordinates_resolution.UIConfig['resolution']))

    def next_station(self, one_loop=False): # 只能在起始站出发 不可以从中间的站点出发
        # one_loop 参数，如果传递为 True，则在遍历完整个数组后，只会进行一次循环。
        # TODO 返回一个封装好的Class 返回Template
        if self.current_station_index == 0: # 如果当前站点是第一个站点，设置方向为向后移动
            self.direction = 1
        elif self.current_station_index == len(self.stations) - 1: # 如果当前站点是最后一个站点，根据参数值设置方向
            
            if one_loop: # 如果只需要循环一次，则不再改变方向，直接返回 False
                self.direction = 0
                return False
            else: # 否则，改变方向为向前移动
                self.direction = -1
        # 计算下一站的索引
        next_index = self.current_station_index + self.direction
        if next_index >= len(self.stations) or next_index < 0: # 如果到达了数组的末尾或开头，则根据参数值返回 False 或 True
            return not one_loop
        self.current_station_index = next_index             # 更新当前站点索引
        return self.stations[self.current_station_index]    # 返回下一站的定位资源
    
    def moveToNextStaion(self,pathNoLoopFlag = False): # 请在MainScreen开始
        if self.gameControllor.resetToMainScreen(): # 重置为游戏主界面
            self.gameControllor.moveToGalaxyAndOpenList()
            nextStationTemplate = self.next_station(pathNoLoopFlag) # 获取下一站的Template
            log("舰队航线控制:下一个前往的星系是:"+str(nextStationTemplate))
            if nextStationTemplate == False:
                log("舰队航线控制:无下一站,已经到达终点站")
                return False
            nextStationCheck = exists(nextStationTemplate)  # Selecct next jump from list
            if nextStationCheck:
                touch(nextStationCheck)     # 准备前往下一站
                sleep(5.0)                  #
                jumpButtonCheck = exists(Template(r"./resources/commonCommand/jumpButton.png", record_pos=(
                    0.309, 0.072), resolution=self.coordinates_resolution.UIConfig['resolution'])) # 是否加载出来了跳跃界面
                if jumpButtonCheck:
                    touch(jumpButtonCheck)
                    self.gameControllor.clickSkipButton()
                    sleep(40.0) # 等待加载时间 注释:此处的加载指进行的跨越星系之间的加载时间 应该尽可能宽裕一些
                    return True
                    # Focus 为了提高效率不进行下面的处理了
                    # 根据头像是否存在来检查是否回到了主界面
                    # if exists(Template(r"./resources/customFeature/playerPic.png", record_pos=(-0.446, -0.231), resolution=(1600, 900))):
                        # return True
                    #else:
                        # 进行更长时间的缓冲加载时间
                        # sleep(15.0)
                        # return True
            else:
                log("舰队航线控制:无下一站,已经到达终点站")
                return False



class CombatCommander:  # 信号任务的战斗 突袭战斗 战斗任务控制模块
    def __init__(self,gameControllor,coordinates_resolution):
        self.autoSkillInterval = 15                      # 自动释放技能间隔
        self.autoTacticsFireFlag = False                 # 自动释放母舰战术技能
        self.autoTacticsFireEvent = threading.Event()    # 创建一个Event对象
        self.coordinates_resolution = coordinates_resolution
        self.gameControllor = gameControllor
        self.autoTacticsFireThread = None
    def combatCommanderInitTest():
        log("CombatCommander init success")

    def tacticsFire(self,slotSequence: int) -> None: # 母舰武器系统战术技能开火栏位 slotSequence技能槽序数
        positions = {
            1: self.coordinates_resolution.UICoordinates['FirstSkill'],
            2: self.coordinates_resolution.UICoordinates['SecondSkill'],
            3: self.coordinates_resolution.UICoordinates['ThirdSkill'],
            4: self.coordinates_resolution.UICoordinates['FourthSkill']
        }
        if slotSequence in positions:
            # log("战斗指挥官:使用第"+str(slotSequence)+"战术技能")
            touch(positions[slotSequence])
    def _autoTacticsFire_loop(self, stop_event):
        while not stop_event.is_set():  # 判断是否需要停止
            for slotIndex in range(3):  # TODO 一般只携带两个技能
                self.tacticsFire(slotIndex)  # 调用tacticsFire方法
            stop_event.wait(self.autoSkillInterval)  # 等待指定的时间

    def autoTacticsFire_start(self, skillInterval=None):
        if skillInterval is not None:
            self.autoSkillInterval = skillInterval

        self.autoTacticsFireFlag = True
        self.autoTacticsFireEvent.clear()  # 初始化Event对象的状态
        # 创建一个新的线程并启动
        self.autoTacticsFireThread = threading.Thread(
            target=self._autoTacticsFire_loop, args=(self.autoTacticsFireEvent,))
        self.autoTacticsFireThread.start()

    def autoTacticsFire_stop(self):
        self.autoTacticsFireFlag = False
        self.autoTacticsFireEvent.set()  # 设置Event对象的状态，通知线程停止
        if self.autoTacticsFireThread is not None: # 等待线程停止
            self.autoTacticsFireThread.join()

    def getSignalMissionType(self): # 获取信号类型并你准备下一个任务类型 返回Template
        # 从Type array中获取一个
        return True
    def enterSignalMethodSettlers(self,UISource):
        if UISource == "Group":         # UI处理
            log("UI控制程序:关闭无关UI")
            self.gameControllor.closeCommunicationLsitUI()   # 关闭通信频道的无关UI 如果是Group进来的话
    def concentrateFirepower(self): # 集中火力于第一个单位 结束后不开启任何列表 列表关闭状态
        touch(self.coordinates_resolution.UICoordinates['RedTargetButton']) # 开启敌人列表 
        sleep(1.0) # 选中第一个Unit
        touch(self.coordinates_resolution.UICoordinates['RedTargetList_FirstTarget'])
        sleep(1.0) # 进行攻击
        touch(self.coordinates_resolution.UICoordinates['EnemyAttackButton'])
        sleep(1.0) # UI加载
        touch(self.coordinates_resolution.UICoordinates['RedTargetButton']) # 关闭敌人列表 
        sleep(1.0) # UI加载


    def jumpToSignal(self,signalJumpUICoordination):
        touch(signalJumpUICoordination)
        self.gameControllor.clickSkipButton()
        sleep(27.5)
        self.gameControllor.clickJoannaSignalJumpSkip()

    def settlementChoose(self,destination):
        if self.gameControllor.rewardSettlement():   # 准备奖励结算和目的地
            if destination == "station":
                # 返回空间站
                self.gameControllor.clickCreditsGoToStationButton()
            elif destination == "stay":
                # 留在原地
                self.gameControllor.clickCreditsStayButton() 
    def ProgenitorSignal(self,signalJumpUICoordination,UISource:str,destination:str):
        log("战斗指挥官:准备进入战场,开始ProgenitorSignal任务")
        self.jumpToSignal(signalJumpUICoordination)
        self.enterSignalMethodSettlers(UISource)
        log("战斗指挥官:开始战场指挥")
        self.gameControllor.openBlueTargetList()
        self.gameControllor.chooseFirstBlueTargetAndIntercept() # 回收

        for index in range(3):
            self.gameControllor.chooseFirstBlueTargetAndIntercept() # 回收
            self.concentrateFirepower()                             # 索敌
            sleep(5.0)                                              # 等待交火
            self.concentrateFirepower()                             # 集火
            self.autoTacticsFire_start(skillInterval=3)             # 释放战术技能
            sleep(15.0)                                             # 交火时间
            self.gameControllor.chooseFirstBlueTargetAndIntercept() # 回收
            self.autoTacticsFire_stop()      
    
        self.settlementChoose(destination)

    def DestroyEnemySignal(self,signalJumpUICoordination,UISource:str,destination:str):
        log("战斗指挥官:准备进入战场,开始DestroyEnemySignal任务")
        self.jumpToSignal(signalJumpUICoordination)
        self.enterSignalMethodSettlers(UISource)
        log("战斗指挥官:开始战场指挥")

        for index in range(2):
            self.concentrateFirepower()                             # 舰队主动攻击
            self.gameControllor.openBlueTargetList()                # 打开菜单
            self.gameControllor.chooseFirstBlueTargetAndIntercept() # 回收
            self.gameControllor.openBlueTargetList()                # 关闭菜单
            sleep(10.0)                                             # 索敌时间
            self.concentrateFirepower()                             # 舰队主动攻击
            self.autoTacticsFire_start(skillInterval=3)             # 释放战术技能
            sleep(10.0)                                             # 交火时间
            self.concentrateFirepower()                             # 舰队主动攻击
            sleep(10.0)                                             # 回收完全
            self.concentrateFirepower()                             # 舰队主动攻击
            self.autoTacticsFire_stop()  
        self.settlementChoose(destination)

    def ProgenitorActivistsSignal(self,signalJumpUICoordination,UISource:str,destination:str):
        log("战斗指挥官:准备进入战场,开始ProgenitorActivistsSignal任务")
        self.jumpToSignal(signalJumpUICoordination)
        self.enterSignalMethodSettlers(UISource)
        log("战斗指挥官:开始战场指挥")
        self.gameControllor.openBlueTargetList()
        self.concentrateFirepower()                             # 索敌
        self.gameControllor.chooseFirstBlueTargetAndIntercept() # 回收
        sleep(10.0)                                             # 等待交火
        self.concentrateFirepower()                             # 集火
        self.autoTacticsFire_start(skillInterval=3)             # 释放战术技能
        self.gameControllor.chooseFirstBlueTargetAndIntercept() # 回收
        sleep(55.0)                                             # 摧毁遗迹
        self.gameControllor.chooseFirstBlueTargetAndIntercept() # 回收
        sleep(55.0)                                             # 摧毁遗迹
        self.gameControllor.chooseFirstBlueTargetAndIntercept() # 回收
        self.autoTacticsFire_stop()      
        self.settlementChoose(destination)

    def RlicSignal(self,signalJumpUICoordination,UISource:str,destination:str): 
        # 处理Relic信号任务 1.前往目标地带 2.回收资源
        log("战斗指挥官:准备进入战场 开始Relic任务")
        self.jumpToSignal(signalJumpUICoordination)
        self.enterSignalMethodSettlers(UISource)
        log("战斗指挥官:开始战场指挥")
        self.gameControllor.openBlueTargetList()
        self.gameControllor.chooseFirstBlueTargetAndMove()

        # Custom Config Part 前去Relic
        self.autoTacticsFire_start(skillInterval=3)   # 开始自动释放战术技能
        sleep(21.0)         # 等待舰队就位 实际上只要发现目标即可 
        self.autoTacticsFire_stop()      # 自动释放战术技能停止

        self.gameControllor.chooseFirstBlueTargetAndIntercept()     # 开始回收

        # Custom Config Part 开始回收资源
        log("战斗指挥官:开始战术技能自动释放")
        self.autoTacticsFire_start(skillInterval=3)   # 开始自动释放战术技能
        sleep(58.0)         # 等待回收完成 这个过程相当的漫长
        log("任务官:回收预计完成")

        self.autoTacticsFire_stop()      # 自动释放战术技能停止
        self.settlementChoose(destination)
        
class OperationOfficer: # 任务管理官 负责处理办公室任务
    def __init__(self,GameControllor_instance,FleetCommander_instance,CombatCommander_instance,coordinates_resolution):
        self.test = True
        self.gameControllor = GameControllor_instance
        self.fleetCommander = FleetCommander_instance
        self.combatCommander = CombatCommander_instance
        self.coordinates_resolution = coordinates_resolution
        self.connectionReadyToWorkFlag = False  # 重置队伍信号内容 当掉线发生时 循环暂停 并且重置
        self.first_execution = True             # 第一次执行的信号

    def initClassTest(self):
        self.gameControllor.gameControllorInitTest()
        self.combatCommander.combatCommanderInitTest()
        self.fleetCommander.fleetCommanderInitTest()
    def operationInit(self):
        self.gameControllor.registerConnectionCheckFlag(self.fleetCommander)
        self.gameControllor.registerConnectionCheckFlag(self)
        self.gameControllor.startCheckLostConnect()  # 连接丢失重连检查
    def enterAsteroidBelt(self): # 进入矿区 随机进入
        self.gameControllor.moveToCombatScreent()   # 打开Combat本地状态
        self.gameControllor.moveToSystemScreen()    # 打开System 
        self.gameControllor.toScan()                # 信号扫描
        self.gameControllor.jumpIntoAsteroidCluster_FirstItem() # 进入第一个小行星带
        self.gameControllor.clickSkipButton()
        sleep(27.5)                                 # 开始跃迁时间到小行星带
        self.gameControllor.clickJoannaSignalJumpSkip()
        
    def miningMineralOperations(self): # 采矿
        self.gameControllor.clickGameBlankSpace()
        touch(self.coordinates_resolution.UICoordinates['Combat_AsteroidClusterButton'])
        sleep(1.0) # UI加载时间
        touch(self.coordinates_resolution.UICoordinates['Combat_AsteroidClusterButton_FirstItem']) # 打开标签页
        sleep(1.0) # UI加载时间
        touch(self.coordinates_resolution.UICoordinates['Combat_AsteroidClusterButton_FirstItem_MoveButton']) 
        sleep(30.0) # 前进时间
        # 选择第一个矿区进行开采
        touch(self.coordinates_resolution.UICoordinates['Combat_AsteroidClusterButton_ForthItem'])
        sleep(2.0)  # UI加载时间
        touch(self.coordinates_resolution.UICoordinates['Combat_AsteroidClusterButton_ForthItem_MineButton'])
        sleep(1.0)  # 关闭列表
        touch(self.coordinates_resolution.UICoordinates['Combat_AsteroidClusterButton']) 

    def stopMiningMineralOperations(self):# 停止采矿工作
        self.gameControllor.moveToGalaxyAndOpenList()   # 打开星系列表
        self.gameControllor.backToCurrentGalaxy()       # 回到星区
        self.gameControllor.clickSkipButton()           # Skip
        sleep(60.0 * 2) # 完全回到主界面

    def unloadingTheCargo(self):# 货舱清空
        touch(self.coordinates_resolution.UICoordinates['InternalButton'])# InternalButton
        sleep(1.0)
        touch(self.coordinates_resolution.UICoordinates['StorageButton'])# Storage
        sleep(1.0)
        # 全部存储 至少循环5次
        for index in range(5):
            touch(self.coordinates_resolution.UICoordinates['MultiSelectButton']) # Multi Select
            sleep(1.0)
            touch(self.coordinates_resolution.UICoordinates['MultiSelectCheckBoxButton']) # Select Checkbox Button 
            sleep(1.0)
            touch(self.coordinates_resolution.UICoordinates['StashButton'])# Stash Button 
            sleep(1.0)
            touch(self.coordinates_resolution.UICoordinates['StashCheckButton'])# Stash Check Button
            sleep(6.0)
        touch(self.coordinates_resolution.UICoordinates['CloseInternalButton']) # 关闭内部空间
        sleep(3.0)

    def simpleMineralOperations(self):
        log("准备存储货舱内容")
        self.unloadingTheCargo()
        log("准备进入小行星带")
        self.enterAsteroidBelt()
        log("开始进入采矿带")
        self.miningMineralOperations()
        self.combatCommander.autoTacticsFire_start(skillInterval=3)     # 自动战斗开启
        sleep(60 * 20)                                                  # 30分钟的采矿作业
        self.combatCommander.autoTacticsFire_stop()                     
        self.stopMiningMineralOperations()
        self.unloadingTheCargo()

    def getSciencePoint(self): # 回收科研点数
        touch(self.coordinates_resolution.UICoordinates['InternalButton']) # InternalButton 
        sleep(1.0)
        touch(self.coordinates_resolution.UICoordinates['ResearchButton']) # 点击科研
        sleep(1.0)
        touch(self.coordinates_resolution.UICoordinates['CollectResearchPoint'])    # 点击回收
        sleep(1.0)
        touch(self.coordinates_resolution.UICoordinates['CloseInternalButton']) # 关闭内部空间
        sleep(1.0)

    def resourceCollectionLoop(self):
        while True:# Loop
            if self.connectionReadyToWorkFlag:  # 隐式被GameControllor控制的变量
                self.combatCommander.autoTacticsFire_stop()  
                log("开始采集矿物任务")
                self.simpleMineralOperations()  # 进行矿物作业
                log("开始收取科研点数")
                self.getSciencePoint()          # 进行科研作业
            else:
                while not self.connectionReadyToWorkFlag:
                    log("检查到掉线情况")
                    self.combatCommander.autoTacticsFire_stop()  
                    sleep(5.0)

    def simpleProgenitorAndRelicGroupSignalLoop(self):
        while True:
            self.gameControllor.openSocial()                # 进入group
            self.combatCommander.ProgenitorSignal(self.coordinates_resolution.UICoordinates['GroupSignalList_AboveSignal'],"Group","stay")    
            self.gameControllor.openSocial()                # 进入group
            self.combatCommander.RlicSignal(self.coordinates_resolution.UICoordinates['GroupSignalList_UnderSignal'],"Group","stay") 

    def simpleRelicAndRelicGroupSignalLoop(self):
        loopCount = 0
        while True:
            self.gameControllor.openSocial()                # 进入group
            self.combatCommander.RlicSignal(self.coordinates_resolution.UICoordinates['GroupSignalList_AboveSignal'],"Group","stay") 
            self.gameControllor.openSocial()                # 进入group
            self.combatCommander.RlicSignal(self.coordinates_resolution.UICoordinates['GroupSignalList_UnderSignal'],"Group","stay") 
            loopCount += 1
            log("循环已经发生了"+str(loopCount))
    def simpleProgenitorActivistsAndProgenitorGroupSignalLoop(self):
        loopCount = 0
        while True:
            self.gameControllor.openSocial()                # 进入group
            self.combatCommander.ProgenitorActivistsSignal(self.coordinates_resolution.UICoordinates['GroupSignalList_AboveSignal'],"Group","stay") 
            self.gameControllor.openSocial()                # 进入group
            self.combatCommander.ProgenitorSignal(self.coordinates_resolution.UICoordinates['GroupSignalList_UnderSignal'],"Group","stay") 
            loopCount += 1
            log("循环已经发生了"+str(loopCount))

    def simpleProgenitorAndDestroyEnemyGroupSignalLoop(self):
        loopCount = 0
        while True:
            self.gameControllor.openSocial()               
            self.combatCommander.ProgenitorSignal(self.coordinates_resolution.UICoordinates['GroupSignalList_AboveSignal'],"Group","stay")  
            self.gameControllor.openSocial()              
            self.combatCommander.DestroyEnemySignal(self.coordinates_resolution.UICoordinates['GroupSignalList_UnderSignal'],"Group","stay")  
            loopCount += 1
            log("UI控制程序:循环已经发生了"+str(loopCount))

    def simpleDestroyEnemyAndDestroyEnemySignalGroupSignalLoop(self):
        loopCount = 0
        while True:
            self.gameControllor.openSocial()               
            self.combatCommander.DestroyEnemySignal(self.coordinates_resolution.UICoordinates['GroupSignalList_AboveSignal'],"Group","stay")  
            self.gameControllor.openSocial()              
            self.combatCommander.DestroyEnemySignal(self.coordinates_resolution.UICoordinates['GroupSignalList_UnderSignal'],"Group","stay")  
            loopCount += 1
            log("UI控制程序:循环已经发生了"+str(loopCount))

    def simpleProgenitorActivistsSignalAndRelicGroupSignalLoop(self):
        loopCount = 0
        while True:
            self.gameControllor.openSocial()               
            self.combatCommander.ProgenitorActivistsSignal(self.coordinates_resolution.UICoordinates['GroupSignalList_AboveSignal'],"Group","stay")  
            self.gameControllor.openSocial()              
            self.combatCommander.RlicSignal(self.coordinates_resolution.UICoordinates['GroupSignalList_UnderSignal'],"Group","stay")  
            loopCount += 1
            log("UI控制程序:循环已经发生了"+str(loopCount))

    def simpleActivistsAndActivistsLoop(self):
        loopCount = 0
        while True:
            self.gameControllor.openSocial()               
            self.combatCommander.ProgenitorActivistsSignal(self.coordinates_resolution.UICoordinates['GroupSignalList_AboveSignal'],"Group","stay")  
            self.gameControllor.openSocial()              
            self.combatCommander.ProgenitorActivistsSignal(self.coordinates_resolution.UICoordinates['GroupSignalList_UnderSignal'],"Group","stay")  
            loopCount += 1
            log("UI控制程序:循环已经发生了"+str(loopCount))
                      
    def signalLoop(self, signal_type):
        signal_mapping = {
            'ProgenitorAndRelic': {
                'above': self.combatCommander.ProgenitorSignal,
                'under': self.combatCommander.RlicSignal
            },
            'RelicAndRelic': {
                'above': self.combatCommander.RlicSignal,
                'under': self.combatCommander.RlicSignal
            },
            'ProgenitorActivistsAndProgenitor': {
                'above': self.combatCommander.ProgenitorActivistsSignal,
                'under': self.combatCommander.ProgenitorSignal
            },
            'ProgenitorActivistsAndRelic': {
                'above': self.combatCommander.ProgenitorActivistsSignal,
                'under': self.combatCommander.RlicSignal
            },
            'ProgenitorActivistsAndProgenitorActivists': {
                'above': self.combatCommander.ProgenitorActivistsSignal,
                'under': self.combatCommander.ProgenitorActivistsSignal
            },
            'DestroyEnemyAndRelic': {
                'above': self.combatCommander.DestroyEnemySignal,
                'under': self.combatCommander.RlicSignal
            },
            'ProgenitorAndDestroyEnemy': {
                'above': self.combatCommander.ProgenitorSignal,
                'under': self.combatCommander.DestroyEnemySignal
            }
        }
        
        loopCount = 0
        while True:
            self.gameControllor.openSocial()  # 进入group
            signal_mapping[signal_type]['above'](self.coordinates_resolution.UICoordinates['GroupSignalList_AboveSignal'], "Group", "stay")
            
            self.gameControllor.openSocial()  # 进入group
            signal_mapping[signal_type]['under'](self.coordinates_resolution.UICoordinates['GroupSignalList_UnderSignal'], "Group", "stay")
            
            loopCount += 1
            log("循环已经发生了" + str(loopCount))


    def withReconnectProgenitorAndRelicGroupSignalLoop(self): # 这个函数执行的第一次应该确定信号是可以刷新出来的状态 会直接开始刷新准备
        log("任务官:开始创建频道和加入Group")
        self.gameControllor.joinChannelAndGroup()  # 准备创建频道并进入小队
        while True:
            log("任务官:开始连接状态,准备执行循环Signal任务")
            if self.connectionReadyToWorkFlag:  # 隐式被GameControllor控制的变量
                self.executeSignalLoop()
            else:
                self.reconnectAndContinue()

    def executeSignalLoop(self):
        log("任务官:连接状态正常,准备按照预定路线刷新Signal")
        if self.first_execution:
            self.first_execution = False
        else:
            self.galaxyFowardWithScan(True)
        self.gameControllor.moveToSystemScreen()
        log("任务官:开始反复扫描")
        self.gameControllor.multipleScan(6)
        log("任务官:开始记录信号")
        self.gameControllor.recordSignalMission()
        while self.connectionReadyToWorkFlag:
            log("任务官:开始信号循环任务")
            self.simpleProgenitorAndRelicGroupSignalLoop()

    def reconnectAndContinue(self):
        log("任务官:失去连接,正在重新连接")
        while not self.connectionReadyToWorkFlag:
            sleep(5.0)
        log("任务官:阻塞结束,准备继续任务")
        log("任务官:开始创建频道和加入Group")
        self.gameControllor.joinChannelAnd

    def cleanLocalSignals(self,GameControllor,CombatCommander):
        # 清理本星系的信号任务 是完全的打完还是仅仅是有限的次数?
        # 进行有限次数的任务 进行2遍 一般一个类型的任务也就出现两遍
        for index in range(2):
            GameControllor.moveToSystemScreen() # 进入System界面
            self.gameControllor.multipleScan(5) # 进行充足的扫描来防止没有刷新
            GameControllor.openSignalList()     # 打开信号列表
            # 准备逐个类型的处理 获得当前信号类型检查任务
            # 获得SignalData 成员 templateObject signalType
            while CombatCommander.get_SignalMissionTypeAndReadyForNext():
            # True or 对应的Object
                signalExistFlag = exists(signalData.templateObject)
                if signalExistFlag: 
                    # !!! 这个地方有错误 应该存在之后然后点击这个任务然后蓝色Start 
                    # 准备战斗
                    log("准备跃迁至信号!进入战斗!")
                    # 通过对应的信号类型进行对应的战斗
                    # 此处的signalExistFlag并不是真的进入战斗的START
                    self.callMethodByName(signalData.signalType,CombatCommander,GameControllor,signalExistFlag,"List","station")
                else:
                    log("没有找到当前信号类型!")
        return True

    def galaxyFowardWithScan(self,pathNoLoopFlag = False): # MainFuncion 从指定星系逐个System扫描 请配置线路
        while True: # 如果路线为单程票或者遇到错误就会停止Script 
            if self.fleetCommander.connectionReadyToWorkFlag == True:   # 如果连接正常那么继续工作
                log("舰队指挥官:舰队信号通畅,准备开始扫描")
                self.gameControllor.moveToSystemScreen()
                self.gameControllor.toScan()
                if self.fleetCommander.moveToNextStaion(pathNoLoopFlag) == False:
                    log("舰队指挥官:无下个跃迁地点,结束任务")
                    return False
                log("舰队指挥官:准备进入下个星系!")
            else:   # 连接失败,进行错误修正
                log("舰队指挥官:等待连接状态恢复")
                while True: # 等待信号重新连接 阻塞舰队行动
                    sleep(60)   # 主线程进行等待直到舰队被通知可以进行任务
                    if self.fleetCommander.connectionReadyToWorkFlag:
                        break   # 阻塞结束 准备继续工作
                self.gameControllor.moveToSystemScreen()
                self.gameControllor.toScan()
                if self.fleetCommander.moveToNextStaion(pathNoLoopFlag) == False:
                    log("舰队指挥官:无下个跃迁地点,结束任务")
                log("舰队指挥官:准备进入下个星系!")
    def NormalGalaxyScan(self): # 简单直接的银河扫描机制
        while True: 
            log("舰队指挥官:舰队信号通畅,准备开始扫描")
            self.gameControllor.moveToSystemScreen()
            self.gameControllor.toScan()
            self.gameControllor.moveToGalaxyAndOpenList()
            self.gameControllor.clickGalaxListFirstItemMoveButton()
            self.gameControllor.clickSkipButton()
            sleep(45.0)                             # 保证战场加载完毕的最小时间
            log("舰队指挥官:准备进入下个星系!")
